using System;
using System.Collections.Generic;
using LiteNetLib.Utils;

namespace Protocols
{
    public struct C2SLogin : INetSerializable
    {
        public string Name { get; set; }
        public string Password { get; set; }

        public void Serialize(NetDataWriter writer)
        {
            writer.Put(Name);
            writer.Put(Password);
        }

        public void Deserialize(NetDataReader reader)
        {
            Name = reader.GetString();
            Password = reader.GetString();
        }
    }

    public class S2CLoginRes : INetSerializable
    {
        public int ErrCode = 0;
        public long UserID = 0;
        public Dictionary<long, MoveData> DictMoveData = new Dictionary<long, MoveData>();

        public void Serialize(NetDataWriter writer)
        {
            writer.Put(ErrCode);
            writer.Put(UserID);

            var cnt = (int)DictMoveData.Count;
            writer.Put(cnt);
            foreach (var item in DictMoveData)
            {
                writer.Put(item.Key);
                item.Value.Serialize(writer);
            }
        }

        public void Deserialize(NetDataReader reader)
        {
            ErrCode = reader.GetInt();
            UserID = reader.GetLong();

            var cnt = reader.GetInt();
            DictMoveData.Clear();

            for (var i = 0; i < cnt; ++i)
            {
                var key = reader.GetLong();
                var val = new MoveData();
                val.Deserialize(reader);
                DictMoveData.Add(key, val);
            }
        }
    }

    public struct S2CLoginNtf : INetSerializable
    {
        public long UserID;
        public string UserName;

        public void Serialize(NetDataWriter writer)
        {
            writer.Put(UserName);
            writer.Put(UserID);
        }

        public void Deserialize(NetDataReader reader)
        {
            UserName = reader.GetString();
            UserID = reader.GetLong();
        }
    }

    public struct S2CDisconnectNtf : INetSerializable
    {
        public long UserID;
        public void Serialize(NetDataWriter writer)
        {
            writer.Put(UserID);
        }

        public void Deserialize(NetDataReader reader)
        {
            UserID = reader.GetLong();
        }
    }

    public struct C2STick : INetSerializable
    {
        public void Serialize(NetDataWriter writer)
        {
        }

        public void Deserialize(NetDataReader reader)
        {
        }
    }

    public class S2CTick : INetSerializable
    {
        public long Now;
        public void Serialize(NetDataWriter writer)
        {           
            writer.Put(Now);
        }

        public void Deserialize(NetDataReader reader)
        {
            Now = reader.GetLong();
        }
    }

    public struct S2CServerStatusNtf : INetSerializable
    {
        public int OnlineCnt;

        public void Serialize(NetDataWriter writer)
        {
            writer.Put(OnlineCnt);
        }

        public void Deserialize(NetDataReader reader)
        {
            OnlineCnt = reader.GetInt();
        }
    }

    public struct MoveData
    {
        public bool move;
        public short dir;
        public float pos_x, pos_y, pos_z;
        public float rotate_x, rotate_y, rotate_z, rotate_w;

        public bool Compare(MoveData data)
        {
            return data.move == move
                   && data.dir == dir
                   && Math.Abs(data.pos_x - pos_x) < 0.0001f
                   && Math.Abs(data.pos_y - pos_y) < 0.0001f
                   && Math.Abs(data.pos_z - pos_z) < 0.0001f
                   && Math.Abs(data.rotate_x - rotate_x) < 0.0001f
                   && Math.Abs(data.rotate_y - rotate_y) < 0.0001f
                   && Math.Abs(data.rotate_z - rotate_z) < 0.0001f
                   && Math.Abs(data.rotate_w - rotate_w) < 0.0001f;
        }

        public void Serialize(NetDataWriter writer)
        {
            writer.Put(move);

            writer.Put(dir);

            writer.Put(pos_x);
            writer.Put(pos_y);
            writer.Put(pos_z);

            writer.Put(rotate_x);
            writer.Put(rotate_y);
            writer.Put(rotate_z);
            writer.Put(rotate_w);
        }

        public void Deserialize(NetDataReader reader)
        {
            move = reader.GetBool();
            dir = reader.GetShort();
            pos_x = reader.GetFloat();
            pos_y = reader.GetFloat();
            pos_z = reader.GetFloat();
            rotate_x = reader.GetFloat();
            rotate_y = reader.GetFloat();
            rotate_z = reader.GetFloat();
            rotate_w = reader.GetFloat();
        }
    }

    public struct C2SPlayerMoveData : INetSerializable
    {
        public MoveData Data;
        public void Serialize(NetDataWriter writer)
        {
            Data.Serialize(writer);
        }

        public void Deserialize(NetDataReader reader)
        {
            Data.Deserialize(reader);
        }
    }

    public struct S2CPlayerMoveDataNtf : INetSerializable
    {
        public long UserID;
        public MoveData Data;

        public void Serialize(NetDataWriter writer)
        {
            writer.Put(UserID);
            Data.Serialize(writer);
        }

        public void Deserialize(NetDataReader reader)
        {
            UserID = reader.GetLong();
            Data.Deserialize(reader);
        }
    }

    public struct C2SChat : INetSerializable
    {
        public string Msg;

        public void Serialize(NetDataWriter writer)
        {
            writer.Put(Msg);
        }

        public void Deserialize(NetDataReader reader)
        {
            Msg = reader.GetString();
        }
    }

    public struct S2CChatNtf : INetSerializable
    {
        public long UserID;
        public string Msg;

        public void Serialize(NetDataWriter writer)
        {
            writer.Put(UserID);
            writer.Put(Msg);
        }

        public void Deserialize(NetDataReader reader)
        {
            UserID = reader.GetLong();
            Msg = reader.GetString();
        }
    }
}
